#include "ThreeDBeamQuality.h"
#include <QDebug>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QPainter>
#include <GL/glu.h>
#include <GL/freeglut.h>
#include <QElapsedTimer>

ThreeDBeamQuality::ThreeDBeamQuality(QWidget *parent) : QOpenGLWidget(parent) {
    setMouseTracking(true); // 启用鼠标跟踪
    rotationX = 0.0f;
    rotationY = 0.0f;
    lastPos = QPoint(0, 0);
    axisLength = 2.0f; // 默认轴长度
    tickInterval = 0.3f; // 默认刻度间隔
    scale = 1.0f; // 默认缩放比例
    m_updateTimer = new QTimer(this);
    m_updateTimer->setSingleShot(true); // 单次触发
    connect(m_updateTimer, &QTimer::timeout, this, [this]() {
        if (m_pendingUpdate) {
            update(); // 触发真正的重绘
            m_pendingUpdate = false;
        }
    });
}

ThreeDBeamQuality::~ThreeDBeamQuality() {
    if (m_updateTimer) {
        delete m_updateTimer;
        m_updateTimer = nullptr;
    }
}

void ThreeDBeamQuality::initializeGL() {
    initializeOpenGLFunctions();
    qDebug() << "OpenGL Version:" << QString((const char*)glGetString(GL_VERSION));
    // glClearColor(25.0f / 255.0f, 35.0f / 255.0f, 45.0f / 255.0f, 1.0f); // #19232D
    glClearColor(50.0f / 255.0f, 65.0f / 255.0f, 75.0f / 255.0f, 1.0f); // #32414B

    glEnable(GL_DEPTH_TEST); // 启用深度测试
    qDebug() << "InitializeGL called";
}

void ThreeDBeamQuality::addEllipse(float xPos, float major, float minor, float angle,const QImage& textureImage) {
    if (!ellipses.empty()) {
        for (int i=0;i<ellipses.size();i++) {
            if (ellipses[i].xPos==xPos)
                return ;
        }
    }
    ellipses.emplace_back(xPos, major, minor, angle,textureImage);

}

void ThreeDBeamQuality::removeEllipse(float xPos) {
    for (auto it = ellipses.begin(); it != ellipses.end(); ) {
        if ((it->xPos - xPos)<1e-1) {
            it = ellipses.erase(it);
        } else {
            ++it;
        }
    }
    update();
}

void ThreeDBeamQuality::paintGL() {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(-0.6f, -0.4f, -5.0f);
    glRotatef(rotationX, 1.0f, 0.0f, 0.0f);
    glRotatef(rotationY, 0.0f, 1.0f, 0.0f);
    glScalef(scale, scale, scale);


    // 固定轴长度
    float axisLength = 2.0f;
    // 计算数据范围
    float dataMinX = 0.0f, dataMaxX = axisLength;
    float tickInterval = 1.0f;
    if (!ellipses.empty()) {
        dataMinX = FLT_MAX;
        dataMaxX = FLT_MIN;

        for (const auto& ellipse : ellipses) {
            dataMinX = std::min(dataMinX, ellipse.xPos);
            dataMaxX = std::max(dataMaxX, ellipse.xPos);
        }

        if (ellipses.size() ==1) {
            dataMinX -= 4;
            dataMaxX += 4;
        }
        else {
            // 给数据范围一些边距
            float dataRange = dataMaxX - dataMinX;
            if (dataRange < 0.1f) dataRange = 0.1f; // 避免除零

            dataMinX -= dataRange * 0.1f;
            dataMaxX += dataRange * 0.1f;
            tickInterval = calculateOptimalTickInterval(dataMinX, dataMaxX);

        }
    }

    // 智能计算刻度参数

    float scaleFactor = axisLength / (dataMaxX - dataMinX);

    // 绘制3D坐标系
    glBegin(GL_LINES);

    // X轴（红色）- 固定长度
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(axisLength, 0.0f, 0.0f);

    // Y轴（绿色）
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, axisLength, 0.0f);

    // Z轴（蓝色）
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, 0.0f, axisLength);

    // 绘制X轴刻度线 - 使用映射后的位置
    for (float t = dataMinX; t < dataMaxX; t += tickInterval) {
        float mappedX = (t - dataMinX) * scaleFactor;
        if (mappedX >= 0 && mappedX <= axisLength) {
            glColor3f(1.0f, 1.0f, 1.0f);
            glVertex3f(mappedX, -0.05f, 0.0f);
            glVertex3f(mappedX, 0.05f, 0.0f);
        }
    }

    // Y轴和Z轴刻度线保持不变
    for (float t = 0.2f; t <= axisLength; t += 0.2f) {
        // Y轴刻度
        glColor3f(1.0f, 1.0f, 1.0f);
        glVertex3f(-0.05f, t, 0.0f);
        glVertex3f(0.05f, t, 0.0f);

        // Z轴刻度
        glColor3f(1.0f, 1.0f, 1.0f);
        glVertex3f(0.0f, -0.05f, t);
        glVertex3f(0.0f, 0.05f, t);
    }
    glEnd();

    // 绘制刻度值
    glColor3f(1.0f, 1.0f, 1.0f);

    // X轴刻度值 - 显示实际数据值，但位置映射到固定轴
    for (float t = dataMinX; t < dataMaxX; t += tickInterval) {
        float mappedX = (t - dataMinX) * scaleFactor;
        if (mappedX >= 0 && mappedX <= axisLength) {
            QString label = formatTickLabel(t); // 智能格式化标签
            std::string stdString = label.toStdString();
            glRasterPos3f(mappedX, -0.15f, 0.0f);
            for (const char* c = stdString.c_str(); *c != '\0'; c++) {
                glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c);
            }
        }
    }

    // Y轴和Z轴刻度值保持不变
    for (float t = 0.2f; t <= axisLength; t += 0.2f) {
        QString label = QString::number(t, 'f', 1);
        std::string stdString = label.toStdString();

        // Y轴
        glRasterPos3f(-0.15f, t, 0.0f);
        for (const char* c = stdString.c_str(); *c != '\0'; c++) {
            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c);
        }

        // Z轴
        glRasterPos3f(0.0f, -0.15f, t);
        for (const char* c = stdString.c_str(); *c != '\0'; c++) {
            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c);
        }
    }

    // 绘制箭头（保持不变）
    glBegin(GL_TRIANGLES);
    // X轴箭头
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex3f(axisLength, 0.0f, 0.0f);
    glVertex3f(axisLength - 0.1f, 0.05f, 0.0f);
    glVertex3f(axisLength - 0.1f, -0.05f, 0.0f);

    // Y轴箭头
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex3f(0.0f, axisLength, 0.0f);
    glVertex3f(0.05f, axisLength - 0.1f, 0.0f);
    glVertex3f(-0.05f, axisLength - 0.1f, 0.0f);

    // Z轴箭头
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex3f(0.0f, 0.0f, axisLength);
    glVertex3f(0.0f, 0.05f, axisLength - 0.1f);
    glVertex3f(0.0f, -0.05f, axisLength - 0.1f);
    glEnd();

    // 绘制轴标签（保持不变）
    glColor3f(1.0f, 1.0f, 1.0f);
    glRasterPos3f(axisLength + 0.1f, 0.0f, 0.0f);
    for (const char* c = "Z [mm]"; *c != '\0'; c++) {
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c);
    }
    glColor3f(1.0f, 1.0f, 1.0f);
    glRasterPos3f(0.0f, axisLength + 0.1f, 0.0f);
    for (const char* c = "Y [mm]"; *c != '\0'; c++) {
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c);
    }
    glColor3f(1.0f, 1.0f, 1.0f);
    glRasterPos3f(0.0f, 0.0f, axisLength + 0.1f);
    for (const char* c = "X [mm]"; *c != '\0'; c++) {
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c);
    }



    // 准备截面点数据
    std::vector<std::pair<float, float>> yPos, yNeg, zPos, zNeg;

    // 绘制椭圆并收集截面点
    for (size_t i = 0; i < ellipses.size(); ++i) {
        if (ellipsesVisible[i] == 0) continue; // 跳过不可见的椭圆
        auto& ellipse = ellipses[i];
        float originalX = ellipse.xPos;
        float mappedX = mapXCoordinate(originalX, dataMinX, scaleFactor);
        ellipse.xPos = mappedX;

        // 绘制椭圆
        ellipse.draw();
        calculateSectionPoints(ellipse, mappedX, yPos, yNeg, zPos, zNeg);
        // 绘制标签（传递当前椭圆和索引）
        drawEllipseLabel(mappedX, originalX, ellipse, i);

        // 恢复原始位置
        ellipse.xPos = originalX;
    }

    drawSectionCurves(yPos, yNeg, zPos, zNeg);
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

}

float ThreeDBeamQuality::calculateOptimalTickInterval(float minVal, float maxVal) {
    float range = maxVal - minVal;
    if (range <= 0) return 1.0f;

    // 计算近似的刻度数量（在固定轴长度上）
    const int targetTicks = 8; // 目标刻度数量
    float roughInterval = range / targetTicks;

    // 找到最接近的"nice"间隔
    float exponent = floor(log10(roughInterval));
    float fraction = roughInterval / pow(10.0f, exponent);

    float niceFraction;
    if (fraction < 1.5f) {
        niceFraction = 1.0f;
    } else if (fraction < 3.0f) {
        niceFraction = 2.0f;
    } else if (fraction < 7.0f) {
        niceFraction = 5.0f;
    } else {
        niceFraction = 10.0f;
    }

    return niceFraction * pow(10.0f, exponent);
}

QString ThreeDBeamQuality::formatTickLabel(float value) {
    // 根据值的大小决定显示精度
    if (fabs(value) < 0.001) {
        return QString::number(value, 'e', 1); // 科学计数法
    } else if (fabs(value) < 1.0) {
        return QString::number(value, 'f', 3); // 3位小数
    } else if (fabs(value) < 10.0) {
        return QString::number(value, 'f', 2); // 2位小数
    } else if (fabs(value) < 100.0) {
        return QString::number(value, 'f', 1); // 1位小数
    } else {
        return QString::number(value, 'f', 0); // 整数
    }
}

void ThreeDBeamQuality::drawHighQualityCurve(const std::vector<std::pair<float, float>>& points,
                             bool isYSection, const float color[4]) {
        if (points.size() < 2) return;

        glColor4fv(color);

        // 如果只有两个点，直接画直线
        if (points.size() == 2) {
            glBegin(GL_LINE_STRIP);
            for (const auto& point : points) {
                if (isYSection) {
                    glVertex3f(point.first, 0.0f, point.second);
                } else {
                    glVertex3f(point.first, point.second, 0.0f);
                }
            }
            glEnd();
            return;
        }

        // 使用自然三次样条插值
        int n = points.size();
        std::vector<float> x(n), y(n);
        for (int i = 0; i < n; i++) {
            x[i] = points[i].first;
            y[i] = points[i].second;
        }

        // 计算二阶导数（使用自然边界条件）
        std::vector<float> y2(n);
        naturalCubicSpline(x, y, y2);

        // 绘制平滑曲线
        glBegin(GL_LINE_STRIP);
        for (int i = 0; i < n - 1; i++) {
            int segments = 20; // 每段之间的插值点数
            for (int j = 0; j <= segments; j++) {
                float t = j / (float)segments;
                float x_val = x[i] + t * (x[i+1] - x[i]);
                float y_val = cubicSplineInterpolate(x[i], x[i+1], y[i], y[i+1], y2[i], y2[i+1], x_val);
             //   qDebug()<<"("<<x_val<<","<<y_val<<")";
                if (isYSection) {
                    glVertex3f(x_val, 0.0f, y_val);
                } else {
                    glVertex3f(x_val, y_val, 0.0f);
                }
            }
        }
    //     qDebug()<<"一轮插值完毕!"<<Qt::endl;
        glEnd();

    }

void ThreeDBeamQuality::naturalCubicSpline(const std::vector<float>& x, const std::vector<float>& y, std::vector<float>& y2) {
    int n = x.size();
    std::vector<float> u(n);

    // 自然边界条件
    y2[0] = 0.0f;
    u[0] = 0.0f;

    // 前向消元
    for (int i = 1; i < n - 1; i++) {
        float sig = (x[i] - x[i-1]) / (x[i+1] - x[i-1]);
        float p = sig * y2[i-1] + 2.0f;
        y2[i] = (sig - 1.0f) / p;
        u[i] = (y[i+1] - y[i]) / (x[i+1] - x[i]) - (y[i] - y[i-1]) / (x[i] - x[i-1]);
        u[i] = (6.0f * u[i] / (x[i+1] - x[i-1]) - sig * u[i-1]) / p;
    }

    // 自然边界条件
    y2[n-1] = 0.0f;

    // 回代
    for (int k = n-2; k >= 0; k--) {
        y2[k] = y2[k] * y2[k+1] + u[k];
    }
}

float ThreeDBeamQuality::cubicSplineInterpolate(float x0, float x1, float y0, float y1, float y20, float y21, float x) {
        float h = x1 - x0;
        if (h == 0.0f) return y0;

        float a = (x1 - x) / h;
        float b = (x - x0) / h;

        return a * y0 + b * y1 + ((a*a*a - a) * y20 + (b*b*b - b) * y21) * (h*h) / 6.0f;
    }

float ThreeDBeamQuality::mapXCoordinate(float originalX, float dataMinX, float scaleFactor) {
    return (originalX - dataMinX) * scaleFactor;
}

void ThreeDBeamQuality::calculateSectionPoints(const MyEllipse& ellipse, float mappedX,
                                        std::vector<std::pair<float, float>>& yPos,
                                        std::vector<std::pair<float, float>>& yNeg,
                                        std::vector<std::pair<float, float>>& zPos,
                                        std::vector<std::pair<float, float>>& zNeg) {
    float angleRad = ellipse.angle * M_PI / 180.0f;

    // Y轴截面 (y=0) - 椭圆与XZ平面的交点
    if (fabs(cos(angleRad)) > 1e-6 || fabs(sin(angleRad)) > 1e-6) {
        if (fabs(fabs(angleRad) - M_PI/2) < 1e-6) {
            // 旋转90°的情况
            yPos.emplace_back(mappedX, ellipse.major);
            yNeg.emplace_back(mappedX, -ellipse.major);
        } else {
            float theta1 = atan2(ellipse.major * cos(angleRad), ellipse.minor * sin(angleRad));
            float theta2 = theta1 + M_PI;

            float z1 = ellipse.major * cos(theta1) * sin(angleRad) + ellipse.minor * sin(theta1) * cos(angleRad);
            float z2 = ellipse.major * cos(theta2) * sin(angleRad) + ellipse.minor * sin(theta2) * cos(angleRad);

            if (z1 > 0) yPos.emplace_back(mappedX, z1);
            else yNeg.emplace_back(mappedX, z1);
            if (z2 > 0) yPos.emplace_back(mappedX, z2);
            else yNeg.emplace_back(mappedX, z2);
        }
    }

    // Z轴截面 (z=0) - 椭圆与XY平面的交点
    if (fabs(cos(angleRad)) > 1e-6 || fabs(sin(angleRad)) > 1e-6) {
        if (fabs(fabs(angleRad) - M_PI/2) < 1e-6) {
            // 旋转90°的情况
            zPos.emplace_back(mappedX, ellipse.minor);
            zNeg.emplace_back(mappedX, -ellipse.minor);
        } else {
            float theta1 = atan2(-ellipse.major * sin(angleRad), ellipse.minor * cos(angleRad));
            float theta2 = theta1 + M_PI;

            float y1 = ellipse.major * cos(theta1) * cos(angleRad) - ellipse.minor * sin(theta1) * sin(angleRad);
            float y2 = ellipse.major * cos(theta2) * cos(angleRad) - ellipse.minor * sin(theta2) * sin(angleRad);

            if (y1 > 0) zPos.emplace_back(mappedX, y1);
            else zNeg.emplace_back(mappedX, y1);
            if (y2 > 0) zPos.emplace_back(mappedX, y2);
            else zNeg.emplace_back(mappedX, y2);
        }
    }
}

void ThreeDBeamQuality::drawSectionCurves(const std::vector<std::pair<float, float>>& yPos,
                                  const std::vector<std::pair<float, float>>& yNeg,
                                  const std::vector<std::pair<float, float>>& zPos,
                                  const std::vector<std::pair<float, float>>& zNeg) {
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glLineStipple(1, 0x00FF); // 虚线样式
    glLineWidth(0.5f);       // 更细的线宽


    const float lightBlue[4] = {0.7f, 0.9f, 1.0f, 0.6f};
    const float lightRed[4] = {1.0f, 0.7f, 0.7f, 0.6f};

    drawHighQualityCurve(yPos, true, lightBlue);
    drawHighQualityCurve(yNeg, true, lightBlue);
    drawHighQualityCurve(zPos, false, lightRed);
    drawHighQualityCurve(zNeg, false, lightRed);

    glDisable(GL_BLEND);
}

void ThreeDBeamQuality::drawEllipseLabel(float xPos, float originalX, const MyEllipse& ellipse, size_t index) {
    glColor3f(1.0f, 1.0f, 1.0f); // 白色标签
    QString label = formatTickLabel(originalX);
    std::string stdString = label.toStdString();

    // 动态调整标签的 Y 坐标，避免重叠
    float labelYOffset = -0.6f - (index % 3) * 0.02f; // 根据索引交替高度

    glRasterPos3f(xPos, labelYOffset, 0.0f);
    for (const char* c = stdString.c_str(); *c != '\0'; c++) {
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, *c);
    }
}

void ThreeDBeamQuality::resizeGL(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    float aspect = (float)w / (float)h;
    float fov = 45.0f;
    float nearPlane = 0.1f;
    float farPlane = 100.0f;
    float f = 1.0f / tan(fov * 0.5f * 3.14159f / 180.0f);
    float projectionMatrix[16] = {
        f / aspect, 0.0f, 0.0f, 0.0f,
        0.0f, f, 0.0f, 0.0f,
        0.0f, 0.0f, (farPlane + nearPlane) / (nearPlane - farPlane), -1.0f,
        0.0f, 0.0f, (2.0f * farPlane * nearPlane) / (nearPlane - farPlane), 0.0f
    };
    glMultMatrixf(projectionMatrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    qDebug() << "ResizeGL called with width:" << w << "and height:" << h;
}


void ThreeDBeamQuality::mousePressEvent(QMouseEvent *event) {
    lastPos = event->pos();
}
void ThreeDBeamQuality::mouseMoveEvent(QMouseEvent *event) {
    int dx = event->position().x() - lastPos.x();
    int dy = event->position().y() - lastPos.y();

    if (event->buttons() & Qt::LeftButton) {
        float sensitivity = 0.5f;
        rotationX += dy * sensitivity;
        rotationY += dx * sensitivity;

        // 节流 update() 调用
        m_pendingUpdate = true;
        if (!m_updateTimer->isActive()) {
            m_updateTimer->start(33);
        }
    }

    lastPos = event->position();
}

void ThreeDBeamQuality::wheelEvent(QWheelEvent *event) {
    float delta = event->angleDelta().y() / 120.0f;
    scale += delta * 0.1f;
    scale = qMax(0.1f, scale);
    update();
}
void ThreeDBeamQuality::clear() {
    ellipses.clear();
    rotationX = 0.0f;
    rotationY = 0.0f;
    scale = 1.0f;
    update();
}

void ThreeDBeamQuality::refresh() {
    update();
}
